
#ifndef _TTG_STRUCTURES_LISTDICTIONARY_
#define _TTG_STRUCTURES_LISTDICTIONARY_
#include "Common/Definitions.h"

#include "BaseDictionary.h"

namespace ttg_internal
{
	namespace structures
	{
		//Enumerator for ListDictionary.
		template <class T, class Iter = std::list<ttg::structures::ReleasableWrapper<T> >::iterator>
		class ListDictionaryEnumerator :public ttg::structures::Enumerator<T *>
		{
			private:
				std::list<ttg::structures::ReleasableWrapper<T> > *ref_data;
				Iter it;
				bool is_first_call;
			public:
				//Creates enumerator for the required ListDictionary data.
				inline ListDictionaryEnumerator(std::list<ttg::structures::ReleasableWrapper<T> > *ref_data)
				{
					this->ref_data = ref_data;
					this->it = ref_data->begin();
					this->is_first_call = true;
				}
				//Enumerator member.
				//Moves to next element. If there aren't any, returns false.
				virtual bool moveNext()
				{
					if (is_first_call)
					{
						is_first_call = false;
						return !ref_data->empty();
					}
					else
					{
						if (it != ref_data->end())
							it++;
						return it != ref_data->end();
					}
				}
				//Enumerator member. 
				//Returns current element.
				virtual T *&current()
				{
					return it->getRef();
				}
				//Enumerator member. 
				//Resets enumerator to initial state.
				virtual void reset()
				{
					it = ref_data->begin();
					is_first_call = true;
				}
		};
		//List-based dictionary.
		template <class T>
		class ListDictionary :public ttg::structures::Dictionary<T>
		{
			protected:
				std::list<ttg::structures::ReleasableWrapper<T> > data;
			public:
				inline ListDictionary(const char *name)
					:ttg::structures::Dictionary<T>(name)
				{ /*nothing*/ }

				virtual bool add(ttg::structures::ReleasableWrapper<T> &no)
				{
					data.push_back(no);
					return true;
				}

				virtual T *get(const char *name)
				{
					std::list<ttg::structures::ReleasableWrapper<T> >::iterator it = data.begin();
					while (it != data.end())
					{
						//std::string n = (*it)->getStringName();
						if (it->get().getStringName() == name)
							return &it->get();
						else
							it++;
					}
					return NULL;
				}

				virtual ttg::structures::Enumerator<T *> *getAll()
				{ return new ListDictionaryEnumerator<T>(&data); }

				virtual T *remove(const char *name)
				{
					std::list<ttg::structures::ReleasableWrapper<T> >::iterator it = data.begin();
					while (it != data.end())
						if (it->get().getStringName() == name)
						{
							T *res = &it->get();
							it->setReleasability(false);
							data.erase(it);
							return res;
						}
						else
							it++;
					return NULL;
				}

				virtual ttg::structures::EnumerableCollection<T *> *removeAll()
				{
					std::vector<T *> *res = new std::vector<T *>();
					std::list<ttg::structures::ReleasableWrapper<T> >::iterator it = data.begin();
					while (it != data.end())
					{
						res->push_back(&it->get());
						it->setReleasability(false);
						it++;
					}
					data.clear();
					return new EnumerableCollection_StlWrapper<T *, std::vector<T *> >(
						ttg::structures::ReleasableWrapper<std::vector<T *> >(res, true));
				}

				virtual ~ListDictionary()
				{ data.clear(); }

		};
	}
}

#endif
